#!/usr/bin/env python
# stoker_py: Implementation of Stoker "py" command
#
# Author:   Mike Murphy (mamurph@cs.clemson.edu)
# Revision: 16 September 2008
#
#   Copyright 2007-2008 Clemson University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
# This material is based upon work supported under a National Science
# Foundation Graduate Research Fellowship. Any opinions, findings,
# conclusions or recommendations expressed in this publication are those of
# the author(s) and do not necessarily reflect the views of the National
# Science Foundation.

import imp, os, os.path, sys
import stoker_base
from stoker_messages import MSG_NO_STOKER_HOOK

class PyData(object):
   def __init__(self, stoker_config, args, target, stdinput):
      self.stoker_config = stoker_config
      self.args = args
      self.target = target
      self.stdinput = stdinput

class PyCommand(stoker_base.CommandObjectBase):
   def __init__(self, stoker_config, opts, args, target):
      stoker_base.CommandObjectBase.__init__(self, stoker_config, opts, args, target)
   #
   def execute(self, stdin=''):
      pydata = PyData(self.stoker_config, self.args[1:], self.target, stdin)
      dirname, pyname = os.path.split(self.args[0].strip())
      if dirname == '':
         dirname = os.getcwd()
      #
      if pyname.endswith('.py'):
         pyname = pyname[0:-3]
      elif pyname.endswith('.pyc') or pyname.endswith('.pyo'):
         pyname = pyname[0:-4]
      #
      code = 0
      out = ''
      err = ''
      meta_module = (None, None, None)
      try:
         meta_module = imp.find_module(pyname, [ dirname ])
         if dirname not in sys.path:
            sys.path.insert(0, dirname)
         act_module = imp.load_module(pyname, *meta_module)
         if 'stoker_hook' in dir(act_module):
            code, out, err = act_module.stoker_hook(pydata)
         else:
            code = 1
            err = MSG_NO_STOKER_HOOK % (pyname)
      except Exception, message:
         code = 2
         # Preserve any err data in the string
         err += 'Exception: ' + str(message)
      if meta_module[0]:
         meta_module[0].close()
      return (code, out, err)
   #
